package com.company.cloud.pay.modules.mgr.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.constant.BaseConstant.EnabledEnum;
import com.company.cloud.common.constant.BaseConstant.YNEnum;
import com.company.cloud.common.constant.BaseReturnEnum;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.common.utils.CheckUtils;
import com.company.cloud.pay.modules.base.entity.PayChannelConfigInfo;
import com.company.cloud.pay.modules.base.service.PayChannelConfigInfoService;
import com.company.cloud.pay.modules.cache.model.PayChannelConfigModel;
import com.company.cloud.pay.modules.cache.model.PayServiceConfigModel;
import com.company.cloud.pay.modules.cache.service.PayCacheService;
import com.company.cloud.pay.modules.cache.utils.PayConvertUtils;
import com.company.cloud.pay.modules.mgr.controller.req.PayChannelConfigQuery4PageParam;
import com.company.cloud.pay.modules.mgr.controller.req.PayChannelConfigSaveParam;
import com.company.cloud.pay.modules.mgr.controller.req.PayChannelConfigUpdateParam;
import com.company.cloud.pay.modules.mgr.controller.req.PayChannelConfigUpdateStateParam;
import com.company.cloud.pay.modules.mgr.service.PayChannelConfigMgrService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.function.Function;

@Service
public class PayChannelConfigMgrServiceImpl implements PayChannelConfigMgrService {

    @Autowired
    private PayChannelConfigInfoService payChannelConfigInfoService;

    @Autowired
    private PayCacheService payCacheService;

    @Override
    public IPage<PayChannelConfigModel> query(PayChannelConfigQuery4PageParam params) {
        IPage<PayChannelConfigInfo> page = payChannelConfigInfoService.page(
                new Page<>(params.getPage(), params.getRows()),
                new QueryWrapper<PayChannelConfigInfo>()
                        .eq(StringUtils.hasText(params.getServiceCode()), "service_code", params.getServiceCode())
                        .eq(StringUtils.hasText(params.getCompanyNo()), "company_no", params.getCompanyNo())
                        .eq(StringUtils.hasText(params.getPayChannelNo()), "pay_channel_no", params.getPayChannelNo())
                        .eq(StringUtils.hasText(params.getTradeType()), "trade_type", params.getTradeType())
                        .eq(StringUtils.hasText(params.getState()), "state", params.getState())
                        .eq("rows_state", EnabledEnum.ENABLED.getCode())
                        .orderByDesc("service_code", "company_no")
        );
        IPage<PayChannelConfigModel> data = page.convert(new Function<PayChannelConfigInfo, PayChannelConfigModel>() {
            @Override
            public PayChannelConfigModel apply(PayChannelConfigInfo entity) {
                return PayConvertUtils.getPayChannelConfigModel(entity);
            }
        });
        return data;
    }


    @Override
    public PayChannelConfigModel save(PayChannelConfigSaveParam params, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(params);
        PayServiceConfigModel payServiceConfig = payCacheService.getPayServiceConfigByDB(params.getServiceCode());
        if (YNEnum.NO.getCode().equals(payServiceConfig.getState())) {
            throw new BusinessException("支付服务已暂停");
        }
        PayChannelConfigInfo entity = payChannelConfigInfoService.getOne(new QueryWrapper<PayChannelConfigInfo>()
                .eq("service_code", params.getServiceCode())
                .eq("company_no", params.getCompanyNo())
                .eq("pay_channel_no", params.getPayChannelNo())
                .eq("trade_type", params.getTradeType())
        );
        if (entity != null) {
            throw new BusinessException("支付渠道已配置");
        }
        entity = new PayChannelConfigInfo();
        entity.setServiceCode(params.getServiceCode());
        entity.setCompanyNo(params.getCompanyNo());
        entity.setPayChannelNo(params.getPayChannelNo());
        if (params.getPayChannelParam() != null) {
            entity.setPayChannelParam(JSON.toJSONString(params.getPayChannelParam()));
        }
        entity.setState(params.getState());
        entity.addCreateParam(userInfo);
        entity.addEditParam(userInfo);
        payChannelConfigInfoService.save(entity);
        return PayConvertUtils.getPayChannelConfigModel(entity);
    }


    @Override
    public PayChannelConfigModel get(Integer id, boolean isCompany, LoginSimpleUserInfo userInfo) {
        if (CheckUtils.isEmpty(id)) {
            throw new BusinessException(BaseReturnEnum.PARAM_NULL);
        }
        PayChannelConfigModel data = payCacheService.getPayChannelConfigByDB(id);
        if (isCompany) {
            if (!data.getCompanyNo().equals(userInfo.getCompanyNo())) {
                throw new BusinessException("非法操作(无权限读取数据)");
            }
        }
        return data;
    }


    @Override
    public PayChannelConfigModel update(PayChannelConfigUpdateParam params, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(params);
        PayChannelConfigInfo entity = payChannelConfigInfoService.getById(params.getId());
        if (entity == null || EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())) {
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        if (params.isCompany()) {
            if (!entity.getCompanyNo().equals(userInfo.getCompanyNo())) {
                throw new BusinessException("非法操作(无权限读取数据)");
            }
        }
        entity.setPayChannelParam(JSON.toJSONString(params.getPayChannelParam()));
        entity.addEditParam(userInfo);
        payChannelConfigInfoService.updateById(entity);
        payCacheService.removePayChannelConfigByCache(entity.getId(), entity.getServiceCode(), entity.getCompanyNo(), entity.getPayChannelNo(), entity.getTradeType());
        return PayConvertUtils.getPayChannelConfigModel(entity);
    }


    @Override
    public void updateState(PayChannelConfigUpdateStateParam params, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(params);
        PayChannelConfigInfo entity = payChannelConfigInfoService.getById(params.getId());
        if (entity == null || EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())) {
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        if (params.isCompany()) {
            if (!entity.getCompanyNo().equals(userInfo.getCompanyNo())) {
                throw new BusinessException("非法操作(无权限读取数据)");
            }
        }
        if (!params.getState().equals(entity.getState())) {
            entity.setState(params.getState());
            entity.addEditParam(userInfo);
            payChannelConfigInfoService.updateById(entity);
            payCacheService.removePayChannelConfigByCache(entity.getId(), entity.getServiceCode(), entity.getCompanyNo(), entity.getPayChannelNo(), entity.getTradeType());
        }
    }


    @Override
    public void del(Integer id, boolean isCompany, LoginSimpleUserInfo userInfo) {
        if (CheckUtils.isEmpty(id)) {
            throw new BusinessException(BaseReturnEnum.PARAM_NULL);
        }
        PayChannelConfigInfo entity = payChannelConfigInfoService.getById(id);
        if (entity == null || EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())) {
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        if (isCompany) {
            if (!entity.getCompanyNo().equals(userInfo.getCompanyNo())) {
                throw new BusinessException("非法操作(无权限读取数据)");
            }
        }
        entity.setRowsState(EnabledEnum.DISABLED.getCode());
        entity.addEditParam(userInfo);
        payChannelConfigInfoService.updateById(entity);
        payCacheService.removePayChannelConfigByCache(entity.getId(), entity.getServiceCode(), entity.getCompanyNo(), entity.getPayChannelNo(), entity.getTradeType());
    }


}
